/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2012-2021. All rights reserved.
 */

package com.huawei.chengdu.meetingdemo.view.dialogs;

import android.content.Context;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;

import com.huawei.chengdu.meetingdemo.consts.ViewNameConts;
import com.huawei.chengdu.meetingdemo.util.LogUtil;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

public final class ViewsFactory {
    /**
     * The logging tag used by this class with com.device.rc.util.log.HLog.
     */
    private static final String TAG = "ViewFactory";
    private static volatile ViewsFactory instance = null;
    private HashMap<String, CreateView> newViews;
    private HashMap<String, BaseView> views;

    private ViewsFactory() {
        newViews = new HashMap<String, CreateView>();
        views = new HashMap<String, BaseView>();
        createView();
    }

    /**
     * 获取HandlerFactory的单例
     *
     * @return HandlerFactory的实例
     */
    public static ViewsFactory getInstance() {
        if (instance == null) {
            synchronized (ViewsFactory.class) {
                if (instance == null) {
                    instance = new ViewsFactory();
                }
            }
        }

        return instance;
    }

    /**
     * 根据名称，获取对应view
     *
     * @param context  Context
     * @param viewName 需要获取的View名字
     * @return BaseView
     */
    public BaseView getBaseView(Context context, String viewName) {
        BaseView baseView = null;
        // 先判空
        if (TextUtils.isEmpty(viewName)) {
            return baseView;
        }
        baseView = views.get(viewName);
        // 判断views中是否已保存，没有则创建并put到views中
        if (baseView == null && newViews.containsKey(viewName)) {
            baseView = newViews.get(viewName).newView(context);
            views.put(viewName, baseView);
        }
        return baseView;
    }

    /**
     * 获取指定名称的view，该view已经确认是从view的树形结构上脱离了
     *
     * @param context            上下文
     * @param viewName           视图名称
     * @param isRemoveFromParent 获取该view的目的是否为了添加到新的viewGroup中
     * @return 指定名称的view
     */

    public BaseView getBaseView(Context context, String viewName, boolean isRemoveFromParent) {
        BaseView baseView = getBaseView(context, viewName);
        if (baseView == null) {
            return baseView;
        }
        if (isRemoveFromParent) {
            if (!detachViewFromParent(baseView.getLayoutView())) {
                removeView(viewName);
                baseView = getBaseView(context, viewName);
            }
        }

        return baseView;
    }

    /**
     * 通过viewName移除ui单元baseview
     *
     * @param viewName 视图名称
     */
    public void removeView(String viewName) {
        BaseView baseView = views.get(viewName);
        if (baseView != null) {
            baseView.destroy();
            views.remove(viewName);
        }
    }

    /**
     * 切换语言
     */
    public void destroyManagerForChangeLag() {
        Iterator<Entry<String, BaseView>> itor = views.entrySet().iterator();
        while (itor.hasNext()) {
            Entry<String, BaseView> entry = itor.next();
            String viewName = entry.getKey();
            // 却换语言时顶部状态栏不移除
            entry.getValue().destroy();
            itor.remove();
        }
    }

    /**
     * 判断名称为viewNmae的View是否已经存在
     *
     * @param viewName 查询的View名字
     * @return View是否已经存在
     */
    public boolean isViewExist(String viewName) {
        return !(views.get(viewName) == null);
    }

    /**
     * 根据view名称，获取对应的BaseView
     *
     * @param viewName view名称
     * @return 具体的某个BaseView
     */
    public BaseView getBaseViewByName(String viewName) {
        return views.get(viewName);
    }

    private void createView() {
        newViews.put(ViewNameConts.ADV_APPLY_HOST_VIEW, context -> {
             return new AdvApplyHostView(context);
        });
        newViews.put(ViewNameConts.EXTEND_MEETING_SETTINGS_VIEW, context -> {
            return new ExtendViewMeetingSettings(context);
        });
        newViews.put(ViewNameConts.CONF_INFO_VIEW, context -> {
             return new MeetingInfoView(context);
        });
        newViews.put(ViewNameConts.ADV_CONF_INFO_VIEW, context -> {
             return new AdvMeetingInfoView(context);
        });
    }

    /**
     * 将当前的要返回的view从其关联的父节点中去除，以便能够加入到其他的viewGroup中去
     *
     * @param child 要获取的view
     * @return 将当前的要返回的view从其关联的父节点中去除，以便能够加入到其他的viewGroup中去
     */
    public boolean detachViewFromParent(View child) {
        if (child == null) {
            return true;
        } else {
            View view = child.getRootView();
            if (view == null) {
                return true;
            }
            if (view instanceof ViewGroup) {
                if (!removeChildView((ViewGroup) view, child)) {
                    LogUtil.info(TAG + " the view hasn't any parent.:" + child.getId() + ", " + child);
                }
            }
            // 如果还能获取到chlid的父节点，证明出了异常,进行强制处理
            if (child.getParent() != null) {
                return false;
            }
        }
        return true;
    }

    private boolean removeChildView(ViewGroup viewGroup, View child) {
        int i = 0;
        while (i < viewGroup.getChildCount()) {
            if (viewGroup.getChildAt(i) == child) {
                viewGroup.removeView(child);
                return true;
            }
            View view = viewGroup.getChildAt(i);
            if (view instanceof ViewGroup) {
                if (removeChildView((ViewGroup) view, child)) {
                    return true;
                }
            }
            i++;
        }
        return false;
    }

    /**
     * 销毁单例，系统回收
     */
    public static void destory() {
        if (instance != null) {
            instance.newViews.clear();
            instance.newViews = null;
            instance.views.clear();
            instance.views = null;
            instance = null;
        }
    }

    interface CreateView {
        /**
         * 创建view
         *
         * @param context 上下文
         * @return View
         */
        BaseView newView(Context context);
    }
}
